#include"../comm/util.hpp"
#include"../comm/log.hpp"
#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/resource.h> // Added for rlimit structure
namespace ns_run
{
    using namespace ns_util;
    using namespace ns_log;
    class Runner
    {
    public:
        static void SetProcLimit(int memory_limit, int cpu_limit)
        {
            struct rlimit mem_limit;
            mem_limit.rlim_cur = memory_limit * 1024; // 设置内存限制为 memory_limit KB
            mem_limit.rlim_max = RLIM_INFINITY; // 设置内存限制为 memory_limit KB
            setrlimit(RLIMIT_AS, &mem_limit); // 设置虚拟内存限制

            struct rlimit cpu_time_limit;
            cpu_time_limit.rlim_cur = cpu_limit; // 设置 CPU 时间限制为 cpu_limit 秒
            cpu_time_limit.rlim_max = RLIM_INFINITY; // 设置 CPU 时间限制为无限
            setrlimit(RLIMIT_CPU, &cpu_time_limit); // 设置 CPU 时间限制
        }
        static int Run(const std::string& file_name,int cpulimit=0,int memlimit=0)
        {
            std::string _Execute=PathUtil::Exe(file_name);
            std::string _stdin=PathUtil::Stdin(file_name);
            std::string _stdout=PathUtil::Stdout(file_name);
            std::string _stderr=PathUtil::Stderr(file_name);
            
            umask(0);
            int stdin_=open(_stdin.c_str(),O_CREAT|O_RDONLY,0664);
            if(stdin_<0)
            {
                LOG(ERROR)<<"没有成功形成stdin文件"<<std::endl;
            }
            int stdout_=open(_stdout.c_str(),O_CREAT|O_WRONLY,0664);
            if(stdout_<0)
            {
                LOG(ERROR)<<"没有成功形成stdout文件"<<std::endl;
            }
            int stderr_=open(_stderr.c_str(),O_CREAT|O_WRONLY,0664);
            if(stderr_<0)
            {
                LOG(ERROR)<<"没有成功形成stderr文件"<<std::endl;
            }
            if(stdin_<0||stdout_<0||stderr_<0)
            {
                return -1;
            }
            int pid=fork();
            if(pid<0)
            {
                close(stdin_);
                close(stdout_);
                close(stderr_);
                LOG(ERROR)<<"创建子进程失败"<<std::endl;
                return -2;
            }
            if(pid==0)
            {
                dup2(stdin_,0);
                dup2(stdout_,1);
                dup2(stderr_,2);
                // 设置资源限制
                SetProcLimit(memlimit, cpulimit);
                execl(_Execute.c_str(),_Execute.c_str(),nullptr);
                exit(1);
                
            }
            else
            {
                close(stdin_);
                close(stdout_);
                close(stderr_);
                int status=0;
                waitpid(pid,&status,0);
                if(WIFEXITED(status))
                {
                    LOG(INFO)<<"程序正常退出，返回值为"<<WEXITSTATUS(status)<<std::endl;
                }
                else if(WIFSIGNALED(status))
                {
                    LOG(ERROR)<<"程序被信号中断，信号值为"<<WTERMSIG(status)<<std::endl;
                }
                else if(WIFSTOPPED(status))
                {
                    LOG(ERROR)<<"程序被信号暂停，信号值为"<<WSTOPSIG(status)<<std::endl;
                }
                else if(WIFCONTINUED(status))
                {
                    LOG(INFO)<<"程序继续运行"<<std::endl;
                }
                return status&0x7f;
            }

        }


    };
}
